/* Scheduler include files. */
#include <stdlib.h>
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "LCDtasks.h"


#define comSTACK_SIZE				(configMINIMAL_STACK_SIZE)//65->70
#define comBUFFER_LEN				1
/* We should find that each character can be queued for Tx immediately and we
don't have to block to send. */
#define comNO_BLOCK					( ( portTickType ) 0 )

/* The LCD task will block on the LCD queue for a long period. */
#define comBLOCK_TIME			( ( portTickType ) 0xffff )
/* The LCD task as described at the top of the file. */
static portTASK_FUNCTION_PROTO( vLCDTask, pvParameters );

static xQueueHandle xLCDQueue;
static char LCD_Buffer[33];
#define  LCD_CMD	0
#define  LCD_DATA	1

void vStartLCDTasks( unsigned portBASE_TYPE uxPriority)
{
	/* Initialise the LCD tasks. */
	//Init LCD
	INIT_LCD();
	unsigned char i;
	for(i = 0; i < 32; i++){
		LCD_Buffer[i] = ' ';
	}
	portENTER_CRITICAL();
	{
		/* Create the queues used by the LCD task. */
		xLCDQueue = xQueueCreate( comBUFFER_LEN, ( unsigned portBASE_TYPE ) sizeof( char *) );
	}
	portEXIT_CRITICAL();
	/* Create The LCD task */
	if(xLCDQueue != 0)
		xTaskCreate( vLCDTask, ( signed char * ) "LCD", comSTACK_SIZE, NULL, uxPriority, ( xTaskHandle * ) NULL );
}

signed portBASE_TYPE xPrintNumLCD(unsigned char position, long OutNum,unsigned char length, portTickType xBlockTime){
	char str[6];
	unsigned char i;
	long tmp = OutNum;
	if(length > 4) i = 4;
	else	i = length;
	str[i+1]=0;
	
	if(tmp >= 0) str[0] = '+';
	else{	str[0] = '-';
		tmp = -tmp;
	}
	for(;i>0;i--){
		str[i]=tmp%10+0x30;
		tmp =tmp/10;
	}
	return xPrintStrLCD(position, str,xBlockTime);
}

signed portBASE_TYPE xPrintStrLCD(unsigned char position, char* OutString, portTickType xBlockTime){
	char * pBuffer = LCD_Buffer;
	unsigned char i;
	LCD_Buffer[32] = LCD_DATA;
	i = position;
	while(i < 32 && OutString[i-position] !=0){
		LCD_Buffer[i] = OutString[i-position];
		i++;
	}
	if( xQueueSend( xLCDQueue,(void *) &pBuffer, xBlockTime ) != pdPASS )
	{
		return pdFAIL;
	}
	return pdPASS;
}

static portTASK_FUNCTION( vLCDTask, pvParameters ){
	char *pxMsgBuf;
	unsigned char i;
	/* Just to stop compiler warnings. */
	( void ) pvParameters;
	for( ;; ){
		/* Get the next LCDMessage from the buffer. */
		if( xQueueReceive( xLCDQueue, (void *)&pxMsgBuf, ( portTickType )comBLOCK_TIME ) )
		{
			if(pxMsgBuf[32] == LCD_DATA){
				HOME_LCD();
				for(i=0; i <32; i++){
					PUT_CHAR_LCD(pxMsgBuf[i]);
					if(i == 15) MOVE_LCD(0,1);
				}
			}
		}
	}	
}